//游戏主要逻辑
//初始化+绑定事件

var mineArray = null; //用于存储生成地雷的数组
//雷区容器
var mineArea = $(".mineArea");

//用于存储正当地图每个格子额外的信息
var tableData = [];

//存储用户插旗的DOM元素
var flagArray = [];

var btns = $$(".level>button");

var flagNum = $(".flagNum");
var mineNumber = $(".mineNum");
//游戏初始化函数


/*
	生成地雷的方法
	@return 返回地雷数组
 */

function initMine() {
    //生成对应长度的数组
    var arr = new Array(curLevel.col * curLevel.row);
    //往数组中填充值
    for (let i = 0; i < arr.length; i++) {
        arr[i] = i;
    }
    //打乱数组
    arr.sort(() => 0.5 - Math.random());
    //只保留对应雷数量的数组长度
    return arr.slice(0, curLevel.mineNum);
}

function clearScene() {
    mineArea.innerHTML = "";
    flagArray = [];
    flagNum.innerHTML = 0;
    mineNumber.innerHTML = curLevel.mineNum;
}

function init() {
    //清空场景
    clearScene();

    //1、随机生成雷
    mineArray = initMine();
    //console.log(mineArray);

    //2.生成所选配置的表格
    var table = document.createElement('table');
    //初始化各自的下标
    var index = 0;
    for (let i = 0; i < curLevel.row; i++) {
        //创建新的一行
        var tr = document.createElement("tr");
        tableData[i] = [];
        for (let j = 0; j < curLevel.col; j++) {
            var td = document.createElement("td");
            var div = document.createElement("div");

            //每一个小格子都对应一个js对象
            //存储额外信息
            tableData[i][j] = {
                row: i,
                col: j,
                type: "number", //格子的属性 数字：number 雷：mine
                value: 0, //周围雷的数量
                index, //格子的下标
                checked: false //是否被检验过
            };

            //为每个div添加下标 方便获取对应格子的下标
            div.dataset.id = index;
            //标记当前的div可插旗
            div.classList.add("canFlag");

            //查看当前格子的下标是否在雷的数组里面
            if (mineArray.includes(tableData[i][j].index)) {
                tableData[i][j].type = "mine";
                div.classList.add("mine");
            }


            td.appendChild(div);
            tr.appendChild(td);
            index++;
        }
        table.appendChild(tr);
    }
    mineArea.appendChild(table);
    console.log(tableData);


    //鼠标点击事件
    mineArea.onmousedown = function (e) {
        //加判断
        if (e.button === 0) {
            //鼠标左键，区域搜索
            searchArea(e.target);
        }
        if (e.button === 2) {
            //右键插旗
            flag(e.target);
        }
    }
}

//显示答案
function showAnswer() {

    //获取所有雷
    var mineArr = $$("td>div.mine");
    for (let i = 0; i < mineArr.length; i++) {
        mineArr[i].style.opacity = 1;
    }
    //遍历用户的插旗
    for (var i = 0; i < flagArray.length; i++) {
        if (flagArray[i].classList.contains("mine")) {
            //插对了
            flagArray[i].classList.add("right");
        } else flagArray[i].classList.add("error");
    }
    mineArea.onmousedown = null;
}

function flat(arr, deep) {
    if (deep > 0)
        return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flat(cur, deep - 1) : cur), [])
    return arr.slice()
}


/**
 * 找到对应dom在tableData里的js对象
 * @param {Object} cell
 */
function getTableItem(cell) {
    var index = cell.dataset.id;
    //console.log(index.jsx);
    var flatTableData = flat(tableData, 2);
    return flatTableData.filter(item => item.index == index)[0];

}

function getBound(obj) {
    var rowTop = obj.row - 1 < 0 ? 0 : obj.row - 1;
    var rowButtom = obj.row + 1 === curLevel.row ? curLevel.row - 1 : obj.row + 1;
    var colLeft = obj.col - 1 < 0 ? 0 : obj.col - 1;
    var colRight = obj.col + 1 === curLevel.col ? curLevel.col - 1 : obj.col + 1;
    return {rowTop, rowButtom, colLeft, colRight};
}

/**
 * 返回周围一圈雷的数量
 */
function findMineNum(obj) {
    //边界判断
    var {rowTop, rowButtom, colLeft, colRight} = getBound(obj);
    var count = 0;
    for (let i = rowTop; i <= rowButtom; i++) {
        for (let j = colLeft; j <= colRight; j++) {
            if (tableData[i][j].type === "mine") count++;
        }
    }
    return count;
}

/**
 * 根据tableData中的js对象，返回对应的div
 * @param obj
 */
function getDom(obj) {
    var divArray = $$("td>div");
    return divArray[obj.index];
}

/** 搜索该单元格周围的九宫格区域
 * @param {Object} cell 用户点击的单元格
 */
function getAround(cell) {
    if (!cell.classList.contains("flag")) {

        cell.parentNode.style.border = "none";
        cell.classList.remove("canFlag");
        //1.获取该dom元素在tableData里面对应的对象
        var tableItem = getTableItem(cell);

        if (!tableItem) return;


        //代表当前的单元格已经被核对
        tableItem.checked = true;

        //查看周围一圈是否有雷 返回雷的数量
        var mineNum = findMineNum(tableItem);
        //周围没有雷
        if (!mineNum) {
            var {rowTop, rowButtom, colLeft, colRight} = getBound(tableItem);
            for (let i = rowTop; i <= rowButtom; i++) {
                for (let j = colLeft; j <= colRight; j++) {
                    if (!tableData[i][j].checked)
                        getAround(getDom(tableData[i][j]));
                }
            }
        } else {
            var cl = [
                "zero",
                "one",
                "two",
                "three",
                "four",
                "five",
                "six",
                "seven",
                "eight"
            ];
            cell.classList.add(cl[mineNum]);
            cell.innerHTML = mineNum;
        }
    }
}

// cell 用户点击的dom元素
//区域搜索
function searchArea(cell) {
    if (cell.classList.contains("mine")) {
        cell.classList.add("error");
        showAnswer();
        alert("you lose!");
        return;
    }
    getAround(cell);
}

/**
 * 判断用户的插旗是否正确
 */
function isWin() {
    for (var i = 0; i < flagArray.length; i++) {
        if (!flagArray[i].classList.contains("mine")) return false;
    }
    return true;
}

/**
 * 游戏结束
 * @param {*} isWin是个布尔值
 */
function gameOver(isWin) {
    var mess = "";
    if (isWin) {
        mess = "游戏胜利，你找出了所有雷"
    } else mess = "游戏失败";
    setTimeout(function () {
        window.alert(mess);
    }, 0);
}

function flag(cell) {
    if (cell.classList.contains("canFlag")) {
        if (!flagArray.includes(cell)) {
            flagArray.push(cell);
            cell.classList.add("flag");

            if (flagArray.length === curLevel.mineNum) {
                //判断是否胜利
                if (isWin()) gameOver(true);
                else gameOver(false);
                showAnswer();
            }
        } else {
            //取消插旗
            var index = flagArray.indexOf(cell);
            flagArray.splice(index, 1);
            cell.classList.remove("flag");
        }
        flagNum.innerHTML = flagArray.length;
    }
}

//绑定事件
function bindEvent() {

    //阻止鼠标默认弹出菜单的右键行为
    mineArea.oncontextmenu = function (e) {
        e.preventDefault();
    }
    //游戏难度选择
    $(".level").onclick = function (e) {
        for (let i = 0; i < btns.length; i++) {
            btns[i].classList.remove("active");
        }
        e.target.classList.add("active");
        switch (e.target.innerHTML) {
            case "初级": {
                curLevel = config.easy;
                break;
            }
            case "中级": {
                curLevel = config.normal;
                break;
            }
            case "高级": {
                curLevel = config.hard;
                break;
            }
        }
        init();
    }
}


//程序入口
function main() {
    //1.初始化
    init();
    //2.绑定事件
    bindEvent();
}

main();
